# coding:utf-8

import os
import string
import wx.lib.rcsizer as rcs
import wx.lib.intctrl
import Config
import Global
import Loading
import ELog

try:
    from agw import fourwaysplitter as FWS
except ImportError:  # if it's not there locally, try the wxPython lib.
    try:
        import wx.lib.agw.fourwaysplitter as FWS
    except ImportError:
        exit()

# 菜单ID
from AppIds import *

import wx.lib.newevent

# Frame start
SERIAL_GENIUS_FS_CHAR = 0x0F
# Slash
SERIAL_GENIUS_SL_CHAR = 0x1F


# 发送数据模块
class Send(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, style=wx.BORDER_DOUBLE)

        ############# 状态信息 ############
        # 该模块是否启用
        self.isUsing = False

        ############# 配置信息 ############
        self.hexMode = False
        self.sendNewLineMode = False
        self.sendTimelyMode = False
        self.sendTimelyInterval = 0
        self.dataBuffer = []
        self.dataHexBuffer = []
        self.sendTimer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.OnSendDataTimer)

        ############# 开始布局 ###########
        gridSizer = rcs.RowColSizer()

        rowTotal = 5
        colTotal = 3

        # 标题
        title = wx.StaticText(self, -1, u"发送")
        title.SetFont(wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD))
        gridSizer.Add(title, pos=(0, 0), size=(1, colTotal), flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)

        # 数据
        self.textSendData = wx.TextCtrl(self, style=wx.TE_MULTILINE)
        self.textSendData.SetFont(wx.Font(10, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
        gridSizer.Add(self.textSendData, pos=(1, 0), size=(1, colTotal), flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
        self.textSendData.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)

        # 十六进制
        self.checkboxHexMode = wx.CheckBox(self, -1, u"十六进制格式")
        self.checkboxHexMode.Bind(wx.EVT_CHECKBOX, self.OnHexMode)
        gridSizer.Add(self.checkboxHexMode, pos=(2, 0), size=(1, colTotal), flag=wx.ALIGN_CENTER_VERTICAL)
        if Config.APP_CONFIG['module_send']['hexMode'] == '1':
            self.checkboxHexMode.SetValue(True)
            self.hexMode = True

        # 发送新行
        self.checkboxNewLine = wx.CheckBox(self, -1, u"发送新行")
        self.checkboxNewLine.Bind(wx.EVT_CHECKBOX, self.OnSendNewLineMode)
        gridSizer.Add(self.checkboxNewLine, pos=(2, 1), size=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL)
        if Config.APP_CONFIG['module_send']['sendNewLine'] == '1':
            self.checkboxNewLine.SetValue(True)
            self.sendTimelyMode = True
        if self.hexMode:
            self.checkboxNewLine.Enable(False)
        else:
            self.checkboxNewLine.Enable(True)

        # 选择发送文件
        self.btnSelectFile = wx.Button(self, -1, u"选择文件")
        self.btnSelectFile.Bind(wx.EVT_BUTTON, self.OnSelectFile)
        gridSizer.Add(self.btnSelectFile, pos=(2, 2), size=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL)

        # 定时发送
        ck = wx.CheckBox(self, -1, u"定时发送(单位ms)")
        ck.Bind(wx.EVT_CHECKBOX, self.OnSendTimely)
        gridSizer.Add(ck, pos=(3, 0), size=(1, 1), flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)

        # 定时发送时间
        self.textSendInterval = wx.lib.intctrl.IntCtrl(self, size=(50, -1))
        gridSizer.Add(self.textSendInterval, pos=(3, 1), size=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL)
        self.textSendInterval.Bind(wx.lib.intctrl.EVT_INT, self.SendIntervalSet)

        self.textSendInterval.SetValue(int(Config.APP_CONFIG['module_send']['sendInterval']))

        # 发送按钮
        btn = wx.Button(self, -1, u"发送")
        self.Bind(wx.EVT_BUTTON, self.OnSendData, btn)
        gridSizer.Add(btn, pos=(4, 0), size=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL)

        # 清空
        btn = wx.Button(self, -1, u"清空")
        self.Bind(wx.EVT_BUTTON, self.OnClearData, btn)
        gridSizer.Add(btn, pos=(4, 1), size=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL)

        gridSizer.AddGrowableCol(2)
        gridSizer.AddGrowableRow(1)

        ############# 结束布局 ###########
        self.SetSizer(gridSizer)
        self.SetAutoLayout(True)

    # 接收到数据
    def RecvData(self, data):
        pass

    # 设置定时发送间隔
    def SendIntervalSet(self, event):
        self.sendTimelyInterval = event.GetEventObject().GetValue()
        Config.APP_CONFIG['module_send']['sendInterval'] = str(self.sendTimelyInterval)
        if self.sendTimer.IsRunning():
            self.sendTimer.Stop()
            self.sendTimer.Start(self.sendTimelyInterval)

    # 定时发送
    def OnSendTimely(self, event):
        self.sendTimelyMode = event.GetEventObject().GetValue()
        if self.sendTimelyMode:
            if Global.SerialGeniusPort and Global.SerialGeniusPort.running:
                if self.sendTimelyInterval <= 0:
                    wx.MessageBox(u'请设置发送间隔', u'提示')
                    event.GetEventObject().SetValue(False)
                else:
                    self.sendTimer.Start(self.sendTimelyInterval)
            else:
                wx.MessageBox(u'请先打开串口', u'提示')
                event.GetEventObject().SetValue(False)
        else:
            if self.sendTimer.IsRunning():
                self.sendTimer.Stop()

    def OnKillFocus(self, event):
        charList = list(self.textSendData.GetValue())
        if self.hexMode:
            validNumberChar = [ord('0'), ord('1'), ord('2'), ord('3'), ord('4'), ord('5'), ord('6'), ord('7'), ord('8'),
                               ord('9'), ord('a'), ord('b'), ord('c'), ord('d'), ord('e'), ord('f'), ord('A'), ord('B'),
                               ord('C'),
                               ord('D'), ord('E'), ord('F')]
            strHex = []
            del self.dataHexBuffer[:]
            for i in range(0, len(charList)):
                if ord(charList[i]) in validNumberChar:
                    strHex.append(charList[i])
                    if len(strHex) == 2:
                        self.dataHexBuffer.append(string.atoi(''.join(strHex), 16))
                        del strHex[:]

            if len(strHex) == 0:
                self.SetSendDataWindow(self.dataHexBuffer)
            else:
                wx.MessageBox(u'十六进制格式不正确')
                self.textSendData.SetFocus()
        else:
            del self.dataBuffer[:]
            for i in range(0, len(charList)):
                self.dataBuffer.append(ord(charList[i]))

    # 清空数据
    def OnClearData(self, event):
        if self.hexMode:
            del self.dataHexBuffer[:]
            self.SetSendDataWindow(self.dataHexBuffer)
        else:
            del self.dataBuffer[:]
            self.SetSendDataWindow(self.dataBuffer)

    # 发送数据Timer
    def OnSendDataTimer(self, event):
        if Global.SerialGeniusPort and Global.SerialGeniusPort.running:
            if self.hexMode:
                Global.SerialGeniusPort.SendAppend(self.dataHexBuffer)
            else:
                Global.SerialGeniusPort.SendAppend(self.dataBuffer)
                if self.sendNewLineMode:
                    Global.SerialGeniusPort.SendAppend([0x0D])
                    Global.SerialGeniusPort.SendAppend([0x0A])

    # 发送数据
    def OnSendData(self, event):
        if Global.SerialGeniusPort and Global.SerialGeniusPort.running:
            if self.hexMode:
                Global.SerialGeniusPort.SendAppend(self.dataHexBuffer)
            else:
                Global.SerialGeniusPort.SendAppend(self.dataBuffer)
                if self.sendNewLineMode:
                    Global.SerialGeniusPort.SendAppend([0x0D])
                    Global.SerialGeniusPort.SendAppend([0x0A])
        else:
            wx.MessageBox(u'请先打开串口', u'提示')

    # 设置十六进制显示模式
    def OnHexMode(self, event):
        Loading.Show()
        self.hexMode = event.GetEventObject().GetValue()
        if self.hexMode:
            self.SetSendDataWindow(self.dataHexBuffer)
            self.checkboxNewLine.Enable(False)
            Config.APP_CONFIG['module_send']['hexMode'] = '1'
        else:
            self.SetSendDataWindow(self.dataBuffer)
            self.checkboxNewLine.Enable(True)
            Config.APP_CONFIG['module_send']['hexMode'] = '0'
        Loading.Hide()

    # 选择发送文件
    def OnSelectFile(self, event):
        dlg = wx.FileDialog(
            self, message=u"请选择需要发送的文件",
            defaultDir=os.getcwd(),
            defaultFile="",
            wildcard="All files (*.*)|*.*",
            style=wx.OPEN | wx.CHANGE_DIR
        )
        if dlg.ShowModal() == wx.ID_OK:
            Loading.Show()
            try:
                path = dlg.GetPaths()
                f = open(''.join(path), 'rb')
                del self.dataHexBuffer[:]
                charList = list(f.read(-1))

                for i in range(0, len(charList)):
                    self.dataHexBuffer.append(ord(charList[i]))

                self.checkboxHexMode.SetValue(True)
                self.hexMode = True
                self.SetSendDataWindow(self.dataHexBuffer)
                Loading.Hide()
            except:
                Loading.Hide()
                ELog.Trace()
        dlg.Destroy()

    # 设置新行发送模式
    def OnSendNewLineMode(self, event):
        self.sendNewLineMode = event.GetEventObject().GetValue()
        if self.sendNewLineMode:
            Config.APP_CONFIG['module_send']['sendNewLine'] = '1'
        else:
            Config.APP_CONFIG['module_send']['sendNewLine'] = '0'

    # 设置发送内容
    def SetSendDataWindow(self, data):
        dataStr = []
        length = len(data)
        # print length
        if self.hexMode:
            for i in range(0, length):
                dataStr.append('%02X ' % data[i])
        else:
            for i in range(0, length):
                if data[i] >= 0x80:
                    dataStr.append('?')
                else:
                    dataStr.append(chr(data[i]))
        self.textSendData.WriteText(''.join(dataStr))
        self.textSendData.SetValue(''.join(dataStr))
